<?php

namespace Telnet\Telnet;

use React\EventLoop\Factory;
use React\Socket\Server;
use React\Socket\ConnectionInterface;
use Telnet\Telnet\Strategy\CmdDiv;
use Telnet\Telnet\Strategy\CmdIncr;
use Telnet\Telnet\Strategy\CmdMul;

class Service {

    const CLASS_NAME_PRE = 'Telnet\\Telnet\\Strategy\\Cmd';
    const METHOD_NAME = 'handleCmd';
    const ADDRESS = '127.0.0.1:8765';

    public static function initServer($address = self::ADDRESS) {
        $loop = Factory::create();
        $socket = new Server($address, $loop);
        echo 'server address '.$address.PHP_EOL;

        $socket->on('connection', function (ConnectionInterface $connection) {
            $connection->write("Hello " . $connection->getRemoteAddress() . "!\n");
            $connection->write("Welcome to this amazing server!\n");
            $connection->write("input quit exit.\n");

            $connection->on('data', function ($data) use ($connection) {
                //去除换行符
                $data = trim($data);

    

                //分割字符串
                $argc = explode(' ', $data);
                if (empty($argc) || $argc[0] == '') {
                    $connection->write("unknown command.\n");
                } 
                // 每次新增命令， 改动太大， 动态加载
                $className = self::CLASS_NAME_PRE.self::convertClassName($argc[0]);

                if (method_exists($className, self::METHOD_NAME)) {
                    call_user_func_array([$className, self::METHOD_NAME], [$argc, $data, $connection]);
                   
                } else {
                    $connection->write("unknown command.\n");
                }
            });
        });
        $socket->on('error', function (Exception $e) {
            echo 'error: ' . $e->getMessage() . PHP_EOL;
        });

        $socket->on('end', function () {
            echo 'ended' . PHP_EOL;
        });
        $socket->on('close', function () {
            echo 'closed' . PHP_EOL;
        });

        $loop->run();

    }

    /**
     * convertClassName cmd参数转驼峰，首字母大写
     * 
     */
    public static function convertClassName(string $s):string {
        //下划线分割， 转驼峰
        $arr = mb_split('_', $s);
        $res = '';
        if (empty($arr)) {
            return $res;
        }
        //循环处理首字母
        foreach ($arr as $v) {
            //也可以全部转成小写后， 再首字母大小， 这些命令就不区分大小写了
            $res .= ucfirst(strtolower($v));
        }
        
        return $res;
    }

}